package com.faker.service;

import com.alibaba.druid.pool.DruidDataSource;
import com.faker.core.jdbc.DataSourceChange;
import com.faker.dao.ConnectionManagerDao;
import com.faker.entity.SysConnection;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ConnectionManagerService {

    /**
     * 将连接存到CONNECTION_MAP中，切换数据源直接获取，减少连接数据库次数
     */
    static Map<String, SysConnection> CONNECTION_MAP = new HashMap<>();


    @Resource
    private ConnectionManagerDao connectionManagerDao;


    /**
     * 测试数据源连接
     *
     * @param sysConnection
     * @return
     */
    //TODO 需要使用数据源切换方法重写
    public String connectionTest(SysConnection sysConnection) {
        String msg = null;
        //创建数据连接池对象
        try {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setConnectionErrorRetryAttempts(2);//失败后重连的次数
            dataSource.setBreakAfterAcquireFailure(true);//请求失败之后中断
            dataSource.setMaxWait(500);//最长等待时间


            dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource.setUrl(sysConnection.getUrl());
            dataSource.setUsername(sysConnection.getUsername());
            dataSource.setPassword(sysConnection.getPassword());


            //创建jdbc模板对象
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            //设置数据源对象
            jdbcTemplate.setDataSource(dataSource);
            //执行sql语句
            jdbcTemplate.queryForObject("SELECT 1", Integer.class);
        } catch (Exception e) {
            msg = e.getCause().getCause().getMessage();
        } finally {
            return msg;
        }
    }

    public SysConnection findConnectionById(Long connectionId) {
        //读取内存中的连接信息，如果内存中没有再读取数据库，提高查询速度
        String key = connectionId.toString();
        SysConnection sysConnection = CONNECTION_MAP.get(key);
        if (sysConnection == null) {
            DataSourceChange.changeDataSource();
            sysConnection = connectionManagerDao.findConnectionById(connectionId);
        }
        return sysConnection;

    }

    public List<SysConnection> getConnectionList() {
        List<SysConnection> list = connectionManagerDao.getConnectionList();
        for (SysConnection sysConnection : list) {
            String key = sysConnection.getConnectionId().toString();
            //使用String作为key，避免使用Long作为key
            CONNECTION_MAP.put(key, sysConnection);
        }
        return list;
    }


    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int insertConnection(SysConnection sysConnection) {
        return connectionManagerDao.insertConnection(sysConnection);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int updateConnection(SysConnection sysConnection) {
        return connectionManagerDao.updateConnection(sysConnection);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int deleteConnection(Long connectionId) {
        return connectionManagerDao.deleteConnection(connectionId);
    }

}
